<template>
  <!-- #ifdef APP-NVUE -->
  <list
      :enableBackToTop="enableBackToTop"
      :loadmoreoffset="lowerThreshold"
      :offset-accuracy="Number(offsetAccuracy)"
      :showScrollbar="showScrollbar"
      :style="[listStyle]"
      class="u-list"
      @loadmore="scrolltolower"
      @scroll="onScroll"
  >
    <slot/>
  </list>
  <!-- #endif -->
  <!-- #ifndef APP-NVUE -->
  <scroll-view
      :enable-back-to-top="enableBackToTop"
      :lower-threshold="Number(lowerThreshold)"
      :scroll-into-view="scrollIntoView"
      :scroll-top="Number(scrollTop)"
      :scroll-with-animation="scrollWithAnimation"
      :show-scrollbar="showScrollbar"
      :style="[listStyle]"
      :upper-threshold="Number(upperThreshold)"
      class="u-list"
      scroll-y
      @scroll="onScroll"
      @scrolltolower="scrolltolower"
      @scrolltoupper="scrolltoupper"
  >
    <view :style="{
			paddingTop: `${offset}px`
		}">
      <slot/>
    </view>
  </scroll-view>
  <!-- #endif -->
</template>

<script>
import props from './props.js';
// #ifdef APP-NVUE
const dom = uni.requireNativePlugin('dom')
// #endif
/**
 * List 列表
 * @description 该组件为高性能列表组件
 * @tutorial https://www.uviewui.com/components/list.html
 * @property {Boolean}      showScrollbar    控制是否出现滚动条，仅nvue有效 （默认 false ）
 * @property {String ｜ Number}  lowerThreshold    距底部多少时触发scrolltolower事件 （默认 50 ）
 * @property {String ｜ Number}  upperThreshold    距顶部多少时触发scrolltoupper事件，非nvue有效 （默认 0 ）
 * @property {String ｜ Number}  scrollTop      设置竖向滚动条位置（默认 0 ）
 * @property {String ｜ Number}  offsetAccuracy    控制 onscroll 事件触发的频率，仅nvue有效（默认 10 ）
 * @property {Boolean}      enableFlex      启用 flexbox 布局。开启后，当前节点声明了display: flex就会成为flex container，并作用于其孩子节点，仅微信小程序有效（默认 false ）
 * @property {Boolean}      pagingEnabled    是否按分页模式显示List，（默认 false ）
 * @property {Boolean}      scrollable      是否允许List滚动（默认 true ）
 * @property {String}      scrollIntoView    值应为某子元素id（id不能以数字开头）
 * @property {Boolean}      scrollWithAnimation  在设置滚动条位置时使用动画过渡 （默认 false ）
 * @property {Boolean}      enableBackToTop    iOS点击顶部状态栏、安卓双击标题栏时，滚动条返回顶部，只对微信小程序有效 （默认 false ）
 * @property {String ｜ Number}  height        列表的高度 （默认 0 ）
 * @property {String ｜ Number}  width        列表宽度 （默认 0 ）
 * @property {String ｜ Number}  preLoadScreen    列表前后预渲染的屏数，1代表一个屏幕的高度，1.5代表1个半屏幕高度  （默认 1 ）
 * @property {Object}      customStyle      定义需要用到的外部样式
 *
 * @example <u-list @scrolltolower="scrolltolower"></u-list>
 */
export default {
  name: 'u-list',
  mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
  watch: {
    scrollIntoView(n) {
      this.scrollIntoViewById(n)
    }
  },
  data() {
    return {
      // 记录内部滚动的距离
      innerScrollTop: 0,
      // vue下，scroll-view在上拉加载时的偏移值
      offset: 0,
      sys: uni.$u.sys()
    }
  },
  computed: {
    listStyle() {
      const style = {},
          addUnit = uni.$u.addUnit
      if (this.width != 0) style.width = addUnit(this.width)
      if (this.height != 0) style.height = addUnit(this.height)
      // 如果没有定义列表高度，则默认使用屏幕高度
      if (!style.height) style.height = addUnit(this.sys.windowHeight, 'px')
      return uni.$u.deepMerge(style, uni.$u.addStyle(this.customStyle))
    }
  },
  provide() {
    return {
      uList: this
    }
  },
  created() {
    this.refs = []
    this.children = []
    this.anchors = []
  },
  mounted() {
  },
  methods: {
    updateOffsetFromChild(top) {
      this.offset = top
    },
    onScroll(e) {
      let scrollTop = 0
      // #ifdef APP-NVUE
      scrollTop = e.contentOffset.y
      // #endif
      // #ifndef APP-NVUE
      scrollTop = e.detail.scrollTop
      // #endif
      this.innerScrollTop = scrollTop
      this.$emit('scroll', Math.abs(scrollTop))
    },
    scrollIntoViewById(id) {
      // #ifdef APP-NVUE
      // 根据id参数，找到所有u-list-item中匹配的节点，再通过dom模块滚动到对应的位置
      const item = this.refs.find(item => item.$refs[id] ? true : false)
      dom.scrollToElement(item.$refs[id], {
        // 是否需要滚动动画
        animated: this.scrollWithAnimation
      })
      // #endif
    },
    // 滚动到底部触发事件
    scrolltolower(e) {
      uni.$u.sleep(30).then(() => {
        this.$emit('scrolltolower')
      })
    },
    // #ifndef APP-NVUE
    // 滚动到底部时触发，非nvue有效
    scrolltoupper(e) {
      uni.$u.sleep(30).then(() => {
        this.$emit('scrolltoupper')
        // 这一句很重要，能绝对保证在性功能障碍的webview，滚动条到顶时，取消偏移值，让页面置顶
        this.offset = 0
      })
    }
    // #endif
  },
}
</script>

<style lang="scss" scoped>
@import "../../libs/css/components.scss";

.u-list {
  @include flex(column);

}
</style>
